<?php


include_once CF_FUNCTIONS . "CF_support.php";
// Classes
/**
 * BasicTable is a class to dumping of data from a database in an array.  This basic version makes an HTML output
 * @package CFtable
 * @author Chris Tyler
 * @version 1.0
 * @BasicTable is the base class for the an extensable HTML table class for array based data.  This provides data display, sorting, filtering, paging and heading functions
 * @copyright 2007-2008 
 */
class CF_TableBasic {
	/**
	* @var array $valuesarray A 2D array of values, an array of associative row arrays, valuesarray[<row number>][<column heading>]
	*/
	var $valuesarray;
	/**
	* @var array $currentrow holds the current associative array row being processed.  Use this to access other values in the same row in make functions.
	*/	
	var $currentrow;
	/**
	* @var array $fieldspec Array describes data and formatting options
	*/	
	var $fieldspec;
	/**
	* @var string $row_status Internal variable for determing odd or even row in table
	*/	
	var $row_status;
	/**
	* @var string $name Name of table, and of entire CRUDset 
	*/	
	var $name;	
	var $col_class_prefix;
	/**
	* @var bool $show_all_rows Set to true to show all rows regardless of fieldspec in basic table
	*/
	var $table_odd_class = 'odd';
	/**
	* @var string $table_even_class Set the name of the class to give odd table rows
	*/	
	var $table_even_class = 'even';	
	/**
	* @var array $keys array for keys as pulled from Request 
	*/  	
    var $keys;
	
	/**
	 *  BasicTable Constructor method will form table from spec and values
	 * Default will show all columns
	 * all checked rows at once.
	 * @param array $the_spec  This is fieldspec array.  defaults to show all rows
	 * @param array $values array.  This is 2d array by rows
	 */
	function __construct( $the_spec = 'all', $valuesarray = '', $name = ''){
		$this->valuesarray = $valuesarray;
		$this->name = $name;
	
		if(is_array($the_spec)){
			$this->fieldspec = $the_spec;
			//$this->show_all_rows = false;
			}
		else{

			$this->fieldspec = $this->default_fs();
			//$this->show_all_rows = true;
			}	
			
	}

	function CF_TableBasic( $the_spec = 'all', $valuesarray = ''){
		$this->__construct($the_spec, $valuesarray);
	}

	function default_fs(){
		if(is_array($this->valuesarray[0])){
		foreach($this->valuesarray[0] as $column=>$value){
			$row_fs['show'] = 1;
			$fieldspec[$column] = $row_fs;
		}
		}
		return $fieldspec;
	}
	
	/**
	 *  set_valuesarray Method will set values array to passed array
     * @param array $dataarray  This is array.  
	 */
	function set_valuesarray($dataarray){
		$this->valuesarray = $dataarray;	
	}	

	function set_name($name){
		$this->name = $name;
	}

	
/**
 * Set FieldSpec Function
 * @param array $thespec - The fieldspec array
 * @param array $thespec [<colname>] - Set for each column, as named in the database query used
 * @param array $thespec [<colname>] ['headname'] (opt) - Name to display on the header for the column.  If not there, will use <colname>
 * @param array $thespec [<colname>] [key] - If set (1), this will be used as a key field for record operations
 * @param array $thespec [<colname>] [show] - If set (1), this column will show in displays.  If 0 or unset, column will not appear
 * @param array $thespec [<colname>] [select] - How to display editable boxes: {T = Text Input, C = Check box (0 or 1), D = drop down) 
 * @param array $thespec [<colname>] [list] = array of values (showvalue, keyvalue) to use in drop-down.  Array is of form:  valueslist [<index integer>][<keyvariablename>][<showvariablename>] Where defaults are keyvariablename = 'keyvalue' showvariable='showvalue' unless re-assigned
 * @param array $thespec [<colname>] [showvalue] - (opt)  Re-assignes the <keyvariablename> to the string specified, instead of 'keyvalue'
 * @param array $thespec [<colname>] [keyvalue] - (opt) Re-assignes the <showvariablename> to the string specified, instead of 'showvalue'
 * @param array $thespec [<colname>] [sort] - Specifies if row header will sort or not, {true, false, (or undefined)}
 * @param array $thespec [<colname>] [filter] - Specifies if row is filtered. if set= 'keyword', then will  bet textbox for LIKE '%keyword%' search.  If set (= 1, but not specific setting ), then will filter using spec from edit criteria ([select],[list],)
 */		
	function set_fieldspec($thespec){
		$this->fieldspec = $thespec;
	}	
	
	/**
	 *  clear_keys_strings Method will clear keys array.  Placehoder, to be expanded
	 */
	function clear_keys_strings(){}
	/**
	 *  make_key_string Method will set keys array.  Empty, Placehoder, to be expanded
	 */ 
	function make_key_string($col_name, $currentvalue){}
	

	/**
	* function to make start of row.  Override / extend in child classes
	* @param int $row_num This is the row number of the dataset
	* @param string $key_string This is the string of key values, defined by make_key_string function
	* @return string Row begining 
	*/
	function make_row_start($row_num){
		if($this->row_status == 'even'){
			$this->row_status = 'odd';
			$rowstart .= "<tr class=\"$this->table_odd_class\">";			
		}
		else{
			$this->row_status = 'even';
			$rowstart .= "<tr class=\"$this->table_odd_class\">";			
		}
		return $rowstart;
	}
	
	/**
	*  make_row_end Method will set create table row end.  returns end tag, to be expanded
	* in derived classes.
	* @param int $row_num Current row number
	*/
	function make_row_end($row_num){
		return "</tr>\n";	
	}
	
	/**
	 *  make_rowval Method will set create table row value.  Returns value in td.
	 * Expanded in derived classes.
	 * @param string $currentvalue Value to show
	 * @param string $col_name NAme of column to show
	 * @param string $current_text Starting text, not used, expend in derived clases
	 */	
	function make_rowval($currentvalue, $col_name, $current_text){
		$fmtfunction = $this->fieldspec[$col_name]['format_as'];
		if(method_exists($this,$fmtfunction)){	
			$currentvalue = $this->$fmtfunction($currentvalue, $col_name);
		}	
		return "<td class='$col_class_prefix$col_name'>$currentvalue</td>";
	}
	/**
	 * process_keys is a placeholder to create concatinated key ids, etc after the $this->keys array is filled
	 * @return string
	 */	
	function process_keys(){
	
	}
	
	/**
	 * maketable will return the table text from the class, for use as the body of a table
	 * @return string
	 */
	function maketable(){
		$table_text = '';
		if(!empty($this->valuesarray)){
		foreach($this->valuesarray as $row_num => $this->currentrow) {	
			$this->clear_keys_strings();  // Clear keys_string
			$row_text = '';
			// populate the keys set for columns identified as keys in keys array
			// and concatinated string
			foreach ($this->fieldspec as $col_name => $thefield){
				if(!empty($thefield['key'])){
					$currentvalue = $this->currentrow[$col_name];
					$this->keys[$col_name] = $this->currentrow[$col_name];

					$this->make_key_string($col_name, $currentvalue);
				}
			
			}
			$this->process_keys();
			// populate the table in the order of the fieldspec, 
			foreach ($this->fieldspec as $col_name => $thefield){
				if(!empty($thefield['show'])){
					$currentvalue = $this->currentrow[$col_name];
					if(!$thefield['allowhtml']){
						$currentvalue = htmlspecialchars($currentvalue,ENT_QUOTES);
						}
					if(!empty($thefield['makefunction'])){
						$makefunction = $thefield['makefunction'];
						if(method_exists($this,$makefunction)){	
							$currentvalue = $this->$makefunction($currentvalue, $col_name);
						}
					}

					$row_text .= $this->make_rowval($currentvalue, $col_name, $row_text);

				}
			} // end for each colucm in fieldspec
			$table_text .= $this->make_row_start($row_num) . $row_text . $this->make_row_end($row_num) ; 
		}// end for each row
		}// end is not empty valuesarray
		return $table_text;	
	}
    
	/**
	 * make_simple_heading will return a heading row of the column name, in order of fieldspecs presented in fields definition
	 * @return string
	 */
	function make_simple_heading(){
		foreach($this->fieldspec AS $col_name => $colspec){
		if(!empty($colspec['show'])){
			$headtext .= '<th>';
			(empty($colspec['headname']))?$headtext .= $col_name: $headtext .= $colspec['headname'] . "</th>\n";
			}
		}
		return $headtext;
	}
	
} // End BasicTable Class

?>